{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "custom_training.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "private_outputs": true,
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "5rmpybwysXGV"
      },
      "source": [
        "##### Copyright 2018 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "cellView": "form",
        "colab_type": "code",
        "id": "m8y3rGtQsYP2",
        "colab": {}
      },
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "hrXv0rU9sIma"
      },
      "source": [
        "# Kisisellestirilmis egitim: Temelleri"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "7S0BwJ_8sLu7"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs/blob/master/site/tr/r1/tutorials/eager/custom_training.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/docs/blob/master/site/tr/r1/tutorials/eager/custom_training.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "k2o3TTG4TFpt"
      },
      "source": [
        "Bir onceki egitim kitapciginda TensorFLow API'sinin makine ogrenmesinin temel yapi taslarindan biri olan otomatik degisimlerde kullanimini gorduk.\n",
        "Bu kitapcikta ise daha onceki kitapciklarda ogrendigimiz TensorFlow ilkellerini basit makine ogrenmesinde kullanacagiz.\n",
        "\n",
        "Bunun disinda TensorFlow icinde soyutlamayi kolaylastiran yuksek seviye sinir agi API'si 'tf.keras'i da bulundurmaktadir. Sinir aglari ile calisanlarin bu yuksek seviye API'larini kullanmalarini siddetle tavsiye ederiz. Fakat, bu kisa kitapcikta saglam temeller olusturmak icin sinir aglari egitiminin ilk ilkelerinden bahsedecegiz."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "3LXMVuV0VhDr"
      },
      "source": [
        "## Kurulum"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "PJ64L90aVir3",
        "colab": {}
      },
      "source": [
        "from __future__ import absolute_import, division, print_function, unicode_literals\n",
        "\n",
        "import tensorflow as tf\n",
        "\n",
        "tf.enable_eager_execution()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "eMAWbDJFVmMk"
      },
      "source": [
        "## Degiskenler\n",
        "\n",
        "TensorFlow'daki Tensorlar sabit(immutable), durumsuz(stateless) nesnelerdir. Fakat makine ogrenmesi modellerinin durumu degiskendir: modeliniz egitiminde ilerledikce ayni kodun yaptigi tahminler farkli davranislar sergilemelidir (bunu dusuk kayipla yapmasini umut ediyoruz!). Yaptiginiz islemler suresunce degisen bu durumu Python'un durumsal bir yazilim dili olmasi ile gosterebiliriz:\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "VkJwtLS_Jbn8",
        "colab": {}
      },
      "source": [
        "# Python durumunu kullanmak\n",
        "x = tf.zeros([10, 10])\n",
        "x += 2  # This is equivalent to x = x + 2, which does not mutate the original\n",
        "        # value of x\n",
        "print(x)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "wfneTXy7JcUz"
      },
      "source": [
        "TensorFlow icerisinde durumsal operasyonlar bulundurmaktadir ve cogu zaman durumun gosterimi icin bunlari kullanmak dusuk-seviye Python gosterimlerinden daha iyidir. Ornegin, modeldeki agirliklari gostermek icin TensorFlow degiskenlerini kullanmak hem kolay hem de verimlidir.\n",
        "\n",
        "TensorFlow hesaplamalarinda kullanildiginda kaydedilen degeri okuyacak olan, Degisken icinde bir deger bulunduran bir nesnedir. TensorFlow degiskenininde kaydedilen degeri degistirmek icin `tf.assign_sub` ve `tf.scatter_update` gibi cesitli operasyonlar bulunmaktadir."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "itxmrMil6DQi",
        "colab": {}
      },
      "source": [
        "v = tf.Variable(1.0)\n",
        "assert v.numpy() == 1.0\n",
        "\n",
        "# Degeri yeniden esleyelim\n",
        "v.assign(3.0)\n",
        "assert v.numpy() == 3.0\n",
        "\n",
        "# tf.square() gibi bir TensorFlow operasyonunda `v`yi kullanmalim ve yeniden esleyelim\n",
        "v.assign(tf.square(v))\n",
        "assert v.numpy() == 9.0"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "-paSaeq1JzwC"
      },
      "source": [
        "Degiskenler kullanilarak yapilan hesaplamalarda egimler otomatik olarak takip edelir. Katistirmalari gosteren Degiskenlerde ise TensorFlow donem donem guncellestirme yapar, ki bunlar hesaplama gucunde ve hafizada verimlidir.\n",
        "\n",
        "Degiskenlerin kullanilmasi ayni zamanda kodunuzu okuyan kisiye bu durumun sabit olmadigini(mutable) belirtir."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "BMiFcDzE7Qu3"
      },
      "source": [
        "## Ornek: Dogrusal modeli uydurmak\n",
        "\n",
        "Simdi 'Tensor', 'GradientTape', ve 'Variable' gibi ogrendigimiz kavramlari bir araya getirip basit bir modeli olusturalim ve egitelim. Bu genel olarak birkac asamadan olusur:\n",
        "\n",
        "1. Modeli tanimla.\n",
        "2. Kayip fonksiyonunu tanimla.\n",
        "3. Egitim verilerini topla.\n",
        "4. Egitim verilerini incele ve \"optimizer\" kullanarak degiskenleri veriye uydur.\n",
        "\n",
        "Bu egitimde, onemsiz bir ornek olan `f(x) = x * W + b` dogrusal modelinin ustunden gececegiz. Bu modelde iki degisken bulunmaktadir - `W` ve `b`. Dahasi, veriyi oyle olusturacagiz ki iyi egitilmis bir model `W = 3.0` ve `b = 2.0` degerlerine sahip olacak."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "gFzH64Jn9PIm"
      },
      "source": [
        "### Modeli tanimlayalim\n",
        "\n",
        "Degiskenleri ve hesaplamalari kapsayacak basit bir sinif tanimlayalim."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "_WRu7Pze7wk8",
        "colab": {}
      },
      "source": [
        "class Model(object):\n",
        "  def __init__(self):\n",
        "    # Degiskeni (5.0, 0.0) degerlerine ilkle\n",
        "    # Normalde bu degerler rasgele verilir.\n",
        "    self.W = tf.Variable(5.0)\n",
        "    self.b = tf.Variable(0.0)\n",
        "\n",
        "  def __call__(self, x):\n",
        "    return self.W * x + self.b\n",
        "\n",
        "model = Model()\n",
        "\n",
        "assert model(3.0).numpy() == 15.0"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "xa6j_yXa-j79"
      },
      "source": [
        "### Kayip fonksiyonunu tanimlayalim\n",
        "\n",
        "Kayip fonksiyonu belirli bir girdiye gore beklenen cikti degeri ile modelin sonuclarinin ne kadar benzedigini hesaplar. Burada standart L2 kaybini kullanalim."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "Y0ysUFGY924U",
        "colab": {}
      },
      "source": [
        "def loss(predicted_y, desired_y):\n",
        "  return tf.reduce_mean(tf.square(predicted_y - desired_y))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "qutT_fkl_CBc"
      },
      "source": [
        "### Egitim verisini toplayalim\n",
        "\n",
        "Biraz gurultulu bir egitim verisi sentezleyelim."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "gxPTb-kt_N5m",
        "colab": {}
      },
      "source": [
        "TRUE_W = 3.0\n",
        "TRUE_b = 2.0\n",
        "NUM_EXAMPLES = 1000\n",
        "\n",
        "inputs  = tf.random_normal(shape=[NUM_EXAMPLES])\n",
        "noise   = tf.random_normal(shape=[NUM_EXAMPLES])\n",
        "outputs = inputs * TRUE_W + TRUE_b + noise"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "-50nq-wPBsAW"
      },
      "source": [
        "Modelimizi egitmeye baslamadan once modelimizin durumuna bir bakalim. Modelin tahminlarini kirmizi ile egittim verisini mavi ile cizecegiz."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "_eb83LtrB4nt",
        "colab": {}
      },
      "source": [
        "import matplotlib.pyplot as plt\n",
        "\n",
        "plt.scatter(inputs, outputs, c='b')\n",
        "plt.scatter(inputs, model(inputs), c='r')\n",
        "plt.show()\n",
        "\n",
        "print('Current loss: '),\n",
        "print(loss(model(inputs), outputs).numpy())"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "sSDP-yeq_4jE"
      },
      "source": [
        "### Egitim dongusunu tanimlayalim\n",
        "\n",
        "Simdi agimiz ve egitim verimiz hazir. Haydi modelimizi egitelim. Egitim verilerini kullanarak modelin degiskenlerini (`W` ve `b`) guncelleyelim ki kayip fonksiyonumuzun degeri [alcalan egim](https://en.wikipedia.org/wiki/Gradient_descent) ile azalsin. `tf.train.Optimizer` gerceklemesi alcalan egimin bircok degisimin yakalar. Bu nedenle bu gerceklemeleri kullanmanizi siddetle tavsiye ederiz. Fakat burada ilk ilkeleri kullanarak olusturdugumuz model icin bu basit matematik islemlerini kendimiz gercekleyecegiz."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "MBIACgdnA55X",
        "colab": {}
      },
      "source": [
        "def train(model, inputs, outputs, learning_rate):\n",
        "  with tf.GradientTape() as t:\n",
        "    current_loss = loss(model(inputs), outputs)\n",
        "  dW, db = t.gradient(current_loss, [model.W, model.b])\n",
        "  model.W.assign_sub(learning_rate * dW)\n",
        "  model.b.assign_sub(learning_rate * db)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "RwWPaJryD2aN"
      },
      "source": [
        "Son olarak, egitim verisinden tekrar tekrar gecerek 'W' ve 'b' degerlerinin nasil evrimlestigini gorelim."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "XdfkR223D9dW",
        "colab": {}
      },
      "source": [
        "model = Model()\n",
        "\n",
        "# W ve b degerlerini daha sonra bir grafikte gostermek icin toplayalim\n",
        "Ws, bs = [], []\n",
        "epochs = range(10)\n",
        "for epoch in epochs:\n",
        "  Ws.append(model.W.numpy())\n",
        "  bs.append(model.b.numpy())\n",
        "  current_loss = loss(model(inputs), outputs)\n",
        "\n",
        "  train(model, inputs, outputs, learning_rate=0.1)\n",
        "  print('Epoch %2d: W=%1.2f b=%1.2f, loss=%2.5f' %\n",
        "        (epoch, Ws[-1], bs[-1], current_loss))\n",
        "\n",
        "# Simdi bunlari cizelim\n",
        "plt.plot(epochs, Ws, 'r',\n",
        "         epochs, bs, 'b')\n",
        "plt.plot([TRUE_W] * len(epochs), 'r--',\n",
        "         [TRUE_b] * len(epochs), 'b--')\n",
        "plt.legend(['W', 'b', 'true W', 'true_b'])\n",
        "plt.show()\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "vPnIVuaSJwWz"
      },
      "source": [
        "## Siradaki adimlar\n",
        "\n",
        "Bu egitim kitapciginda `Variable(Degisken)`leri gozden gecirdik ve TensorFlow ilkellerini kullanarak basit dogrusal bir model egittik.\n",
        "\n",
        "Teoride bunlar TensorFlow'u makine ogrenmesi arastirmalarinda kullanmanizda yeterlidir.\n",
        "Pratikte, ozellikle sinir aglari icin, yuksek seviye yapi taslari (\"layers(katmanlar)\"), durumu(state) kaydetme ve geri yukleme imkanlari, cok sayida kayip fonksiyonu ve eniyileme taktikleri sundugu icin `tf.keras` gibi yuksek seviye API kullanimi cok daha kolay olacaktir.\n"
      ]
    }
  ]
}